/*
 * Dijjer - A Peer to Peer HTTP Cache
 * Copyright (C) 2004,2005 Change.Tv, Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package dijjer.io.xfer.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import dijjer.io.BlockInfo;
import dijjer.io.comm.RetrievalException;
import dijjer.io.store.Store;
import dijjer.io.xfer.InputStreamBlockReceiver;
import dijjer.io.xfer.PartiallyReceivedBlock;
import dijjer.util.Misc;
import dijjer.util.logging.Logger;

/**
 * @author ian
 * 
 * To change the template for this generated type comment go to Window - Preferences - Java - Code Generation - Code and
 * Comments
 */
public class HttpBlockReceiver {

	protected URL _url;
	protected int _blockNumber;
	protected PartiallyReceivedBlock _prb;
	protected long _totalLength;

	public HttpBlockReceiver(BlockInfo bi, PartiallyReceivedBlock prb) {
		this(bi.getUrl(), bi.getFileLength(), bi.getBlockNo(), prb);
	}

	public HttpBlockReceiver(URL url, long totalLength, int blockNumber, PartiallyReceivedBlock prb) {
		_url = url;
		_blockNumber = blockNumber;
		_prb = prb;
		_totalLength = totalLength;
	}

	public void start() throws IOException, RetrievalException {
		Logger.debug("Beginning http retrieval of "+_url+" block "+_blockNumber);
		URL actualURL = _url;
		HttpURLConnection uc;
		while (!_prb.isAborted()) {
			uc = Misc.openHttpUrlConnection(actualURL);
			long rangeStart = (Store.DATA_BLOCK_SIZE * _blockNumber);
			long rangeEnd = (Math.min(_totalLength, Store.DATA_BLOCK_SIZE * (_blockNumber + 1)) - 1);
			uc.setRequestProperty("Range", "bytes=" + rangeStart + "-" + rangeEnd);
			// Prevent hangs, suggested in:
			// http://forum.java.sun.com/thread.jspa?threadID=17410&messageID=42113
			System.setProperty("sun.net.client.defaultConnectTimeout", "20000");
			System.setProperty("sun.net.client.defaultReadTimeout", "20000");
			uc.connect();
			if (uc.getHeaderField("Location") != null) {
				actualURL = new URL(uc.getHeaderField("Location"));
				uc.disconnect();
				continue;
			}
 			if (uc.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
 				//416 loop error occurs (occurred?) here
  				uc.disconnect();
  				_prb.abort(RetrievalException.UNKNOWN, "Server responded with response code: " + uc.getResponseCode());
  				continue;
  			}
			
			//Stuff below here is only executed once 
			InputStream is = uc.getInputStream();
			InputStreamBlockReceiver isrb = new InputStreamBlockReceiver(_prb, is);
			isrb.start();
			break;
		}
	}
}
